package com.hd.common.security.service;

import cn.hutool.core.lang.UUID;
import com.hd.common.core.constants.CacheConstants;
import com.hd.common.core.constants.JwtConstants;
import com.hd.common.redis.service.RedisService;
import com.hd.common.core.domain.LoginUser;
import com.hd.common.core.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

//提供操作用户登录token的方法
@Service
@Slf4j
public class TokenService {

    @Autowired
    private RedisService redisService;

    public String createtoken(Long userId,String secret,Integer identity){
        Map<String,Object> clamis  = new HashMap<>();
        String userKey = UUID.fastUUID().toString();
        clamis.put(JwtConstants.LOGIN_USER_ID,userId);
        clamis.put(JwtConstants.LOGIN_USER_KEY,userKey);
        String token = JwtUtils.createToken(clamis, secret);
        // 解决第三方存储的敏感信息  使用Redis  key value

        // key保证唯一，便于维护 统一前缀:logintoken,userId，雪花算法进行保证
        // 身份验证需要储存什么信息

        // 存储用到那些数据结构  String

        // 过期时间我们应该怎么进行记录   过期时间应该设置多少是比较合适的  2~3小时

        String tokenKey = getTokenKey(userKey);
        LoginUser loginUser = new LoginUser();
        loginUser.setIdentity(identity);
        redisService.setCacheObject(tokenKey,loginUser,CacheConstants.EXP, TimeUnit.MINUTES);

        return token;
    }

    // 延长token的有效时间，就是延长Redis当中用于存储用户身份验证的敏感信息的有效时间
    // 肯定得身份验证之后进行token的延长时间，并且是在请求到达controller层之前  拦截器
    // 操作Redis
    public void extendToken(String token,String secret){
        Claims claims;
        try {
            claims = JwtUtils. parseToken (token, secret); //获取令牌中信息 解析payload中信息 存储用户的唯一的标识信息
            if (claims == null) {
                // 直接进行返回，打印日志
                log.error("解析token失败：{},出现异常",token);
                return;
            }
        } catch (Exception e) {
                log.error("解析token失败：{},出现异常",token,e);
                return;
        }
        String userKey = JwtUtils. getUserKey (claims); //获取jwt中的key
        String tokenKey = getTokenKey(userKey);
        //  720min   12小时     剩余180min 的时候进行延长
        Long expire = redisService.getExpire(tokenKey,TimeUnit.MINUTES);
        if(expire !=null && expire < CacheConstants.RESFESH_TIME){
            redisService.expire(tokenKey,CacheConstants.EXP,TimeUnit.MINUTES);
        }

    }

    private String getTokenKey(String userKey){
        return CacheConstants.LOGIN_TOKEN_KEY +userKey;
    }
}
